package com.lineage.server.timecontroller.skill;

import com.lineage.server.datatables.SkillsTable;
import com.lineage.server.model.Instance.L1EffectInstance;
import com.lineage.server.model.Instance.L1EffectType;
import com.lineage.server.model.Instance.L1MonsterInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.L1CastleLocation;
import com.lineage.server.model.L1Character;
import com.lineage.server.model.L1Cube;
import com.lineage.server.model.L1Object;
import com.lineage.server.serverpackets.S_OwnCharAttrDef;
import com.lineage.server.serverpackets.S_SkillSound;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.timecontroller.server.ServerWarExecutor;
import com.lineage.server.world.World;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class EffectCubeExecutor {
  private static final Log _log = LogFactory.getLog(EffectCubeExecutor.class);
  
  private static EffectCubeExecutor _instance;
  
  protected static EffectCubeExecutor get() {
    if (_instance == null)
      _instance = new EffectCubeExecutor(); 
    return _instance;
  }
  
  protected void cubeBurn(L1EffectInstance effect) {
    try {
      Iterator<L1Object> iterator = World.get().getVisibleObjects((L1Object)effect, 3).iterator();
      while (iterator.hasNext()) {
        L1Object objects = iterator.next();
        if (objects == null)
          continue; 
        if (objects instanceof L1PcInstance) {
          L1PcInstance pc = (L1PcInstance)objects;
          if (pc.isDead())
            continue; 
          if (effect.get_showId() != pc.get_showId())
            continue; 
          if (effect.getMaster() == null)
            continue; 
          L1PcInstance user = (L1PcInstance)effect.getMaster();
          if (pc.getId() == user.getId()) {
            cubeToAlly((L1Character)pc, effect);
            continue;
          } 
          if (pc.getClanid() != 0 && user.getClanid() == pc.getClanid()) {
            cubeToAlly((L1Character)pc, effect);
            continue;
          } 
          if (pc.isInParty() && pc.getParty().isMember(user)) {
            cubeToAlly((L1Character)pc, effect);
            continue;
          } 
          if (pc.isSafetyZone()) {
            boolean isNowWar = false;
            int castleId = L1CastleLocation.getCastleIdByArea((L1Character)pc);
            if (castleId > 0)
              isNowWar = ServerWarExecutor.get().isNowWar(castleId); 
            if (!isNowWar)
              continue; 
            cubeToEnemy((L1Character)pc, effect);
            continue;
          } 
          cubeToEnemy((L1Character)pc, effect);
          continue;
        } 
        if (!(objects instanceof L1MonsterInstance))
          continue; 
        L1MonsterInstance mob = (L1MonsterInstance)objects;
        if (mob.isDead())
          continue; 
        cubeToEnemy((L1Character)mob, effect);
      } 
    } catch (Exception e) {
      _log.error("Npc L1Effect幻术师技能(立方)状态送出时间轴发生异常", e);
      effect.deleteMe();
    } 
  }
  
  private static void cubeToAlly(L1Character cha, L1EffectInstance effect) {
    int castGfx = SkillsTable.get().getTemplate(effect.getSkillId()).getCastGfx();
    L1PcInstance pc = null;
    int skillid = cubeToAllyId(effect.effectType());
    if (!cha.hasSkillEffect(skillid)) {
      switch (effect.effectType()) {
        case isCubeBurn:
          cha.addFire(30);
          break;
        case isCubeEruption:
          cha.addEarth(30);
          break;
        case isCubeShock:
          cha.addWind(30);
          break;
      } 
      if (cha instanceof L1PcInstance) {
        pc = (L1PcInstance)cha;
        pc.sendPackets((ServerBasePacket)new S_OwnCharAttrDef(pc));
        pc.sendPackets((ServerBasePacket)new S_SkillSound(pc.getId(), castGfx));
      } 
      cha.broadcastPacketX10((ServerBasePacket)new S_SkillSound(cha.getId(), castGfx));
      cha.setSkillEffect(skillid, 8000);
      if (effect.effectType() == L1EffectType.isCubeHarmonize) {
        L1Cube cube = new L1Cube((L1Character)effect, cha, 1025);
        cube.begin();
      } 
    } 
  }
  
  private static void cubeToEnemy(L1Character cha, L1EffectInstance effect) {
    int castGfx2 = SkillsTable.get().getTemplate(effect.getSkillId()).getCastGfx2();
    L1PcInstance pc = null;
    int skillid = cubeToEnemyId(effect.effectType());
    if (!cha.hasSkillEffect(skillid)) {
      if (cha instanceof L1PcInstance) {
        pc = (L1PcInstance)cha;
        pc.sendPackets((ServerBasePacket)new S_SkillSound(pc.getId(), castGfx2));
      } 
      cha.broadcastPacketX10((ServerBasePacket)new S_SkillSound(cha.getId(), castGfx2));
      cha.setSkillEffect(skillid, 8000);
      L1Cube cube = new L1Cube((L1Character)effect, cha, skillid);
      cube.begin();
    } 
  }
  
  private static int cubeToAllyId(L1EffectType effectType) {
    int cubeToAllyId = 0;
    switch (effectType) {
      case isCubeBurn:
        cubeToAllyId = 1018;
        break;
      case isCubeEruption:
        cubeToAllyId = 1020;
        break;
      case isCubeHarmonize:
        cubeToAllyId = 1025;
        break;
      case isCubeShock:
        cubeToAllyId = 1022;
        break;
    } 
    return cubeToAllyId;
  }
  
  private static int cubeToEnemyId(L1EffectType effectType) {
    int cubeToEnemyId = 0;
    switch (effectType) {
      case isCubeBurn:
        cubeToEnemyId = 1019;
        break;
      case isCubeEruption:
        cubeToEnemyId = 1021;
        break;
      case isCubeHarmonize:
        cubeToEnemyId = 1025;
        break;
      case isCubeShock:
        cubeToEnemyId = 1023;
        break;
    } 
    return cubeToEnemyId;
  }
}
